home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga CD-Sensation: Golden Games
/
Amiga CD-Sensation - Ausgabe 2 - Golden Games (1996)(GTI - Schatztruhe)(DE)[!].iso
/
Board & Card
/
Backgammon
/
RNG.asm
< prev
Wrap
Assembly Source File
|
1995-07-01
|
5KB
|
136 lines
; June 19, 1995
; This program is a pair of subroutines I use to generate random
; number is assembly langauge. The first subroutine is called at
; the start of the program to initialize the seeds to unique values.
; This is done using the currenttime function of intuition. Thus,
; S2 which is set to the microseconds value has a 1 in 1,000,000
; chance of starting at the same value as any given previous run.
; S1 should always be unique.
; The second subroutine is based on the algorithm of Pierre L'Ecuyer
; [L'Ecuyer, P. Efficient and Portable Combined Random Number Generators.
; _Commun._ASM_31_, 6 (June, 1988) 742]. Please see the original
; article for a detailed explanation.
;
; These programs were written to be used by any 68000 type processor
; and can be assembled using the a68k assembler. They can be incorp-
; orated into programs directly or by linking the object code if
; setseed, randnum, intubase, and mathbase are xdef'ed in this routine
; and xref'ed in the main program.
; Distribution: These routines are intended as freeware and their
; distribution is restricted as follows:
;
; Source code: The source code must be accompanied by all comments
; include the introductory comments and the program comments.
; No fee may be charged for distribution of the code.
; Executable code: The executable version of these routines may be used if:
; 1) The documentation of the main program includes the
; following text:
; "This program uses the L'Ecuyer random number generator
; as written for the amiga by Scott McMahan."
; 2) The main program using these routines is either freeware
; or the author(s) have the express, written consent of me,
; Scott McMahan.
; (No big deal here, I just don't want to pay for shareware
; that uses my routine. Permission will be easy to get.)
;
;To contact the author and/or make bug reports, mail me at
; Scott McMahan
; 2538 Fairfield Pl #1
; Madison, WI 53704
; Sorry, no Email because I expect my email address to be changing in
; the next 6 months and then again in the next 2 years.
CurrentTime equ -$0054
IEEEDPFlt equ -$0024
IEEEDPDiv equ -$0054
;Routine to set up S1 and S2 (seeds for random number generator)
;based on currenttime function
;parameters: none
;presets: intubase= base address of
; intuition.library
; CurrentTime= offset for currenttime
; function of intuition
;returns: none
;changed regs/mem locations: none/S1,S2
section text,code
xdef @setseed
@setseed:
; movem.l A0/A1,-(A7) ;save registers ******
lea S1(A4),A0 ;get the current seconds and
lea S2(A4),A1 ;microseconds as seeds
move.l _IntuitionBase(A4),A6
jsr CurrentTime(A6) ;in S1 and S2
addq.l #1,S1(A4) ;add one to S1 and S2 to make sure greater than 0
addq.l #1,S2(A4)
cmpi.l #$7FFFFFAA,S1(A4) ;make sure S1<=2147483562
ble.S 20$
subi.l #$7FFFFFAA,S1(A4)
20$ cmpi.l #$7FFFFF06,S2(A4) ;make sure S2<=2147483398
ble.S 30$
subi.l #$7FFFFF06,S2(A4)
30$ ; movem.l (A7)+,A0/A1 ******
rts
;Routine to generate a random number from 0 to 1
;using S1 and S2 as seeds
;Parameters: S1 and S2 Seeds
;presets mathbase = base address of
; mathieeedoubbas.library
; IEEEDPFlt= Offset of int to IEEE
; routine
; IEEEDPDiv= Offset of IEEE division
; routine
;Returns: D0/D1 = Random number from 0 to 1
; in IEEE double precision
;Changed regs/mem locations D0,D1/S1,S2
xdef @random
; section rand,code ******
@random movem.l D2/D3/A6,-(A7)
move.l S1(A4),D1
divu #$D1A4,D1 ;D1=S1 DIV 53668 (k in article)
move.l D1,D0 ;D0 also equals k
swap D1
mulu #$9C4E,D1 ;D1=40014*(S1-k*53668)
mulu #$2FB3,D0 ;D0=12211*k
sub.l D0,D1 ;D1=40014*(S1-k*53668)-12211*k
; tst.l D1 ******
bgt.S 20$ ;if D1<1
add.l #$7FFFFFAB,D1 ;then D1=D1+2147483563
20$ move.l D1,S1(A4) ;store D2 in S1 as new seed
move.l S2(A4),D1
divu #$CE26,D1 ;D1=S2 DIV 52774 (k in article)
move.l D1,D0 ;D0 also equals k
swap D1
mulu #$9EF4,D1 ;D1=40692*(S1-k*52774)
mulu #$0ECF,D0 ;D0=3791*k
sub.l D0,D1 ;D1=40692*(S1-k*52774)-3791*k
; tst.l D1
bgt.S 30$ ;if D1<1
add.l #$7FFFFF07,D1 ;then D1=D1+2147483399
30$ move.l D1,S2(A4) ;store D2 in S2 as new seed
move.l S1(A4),D0
sub.l S2(A4),D0 ;D0=S1-S2
; tst.l D0 ******
bge.S 40$ ;if D0<0
add.l #$7FFFFFA9,D0 ;then D0=D0+2147483562
40$ move.l _MathIeeeDoubBasBase(A4),A6
jsr IEEEDPFlt(A6) ;convert it to IEEE Double Precision
move.l #$41DFFFFF,D2 ;
move.l #$EA800000,D3 ;
jsr IEEEDPDiv(A6) ;Divide it by 2147483562
movem.l (A7)+,D2/D3/A6
rts
section __MERGED,BSS
; even ******
xref _IntuitionBase
xref _MathIeeeDoubBasBase
S1: ds.l 1 ;first seed for generator, set to seconds by
;currenttime
S2: ds.l 1 ;second seed for generator, set to microsecs
;by currenttime
end